#include "symboltablewidget.h"
#include "ui_symboltablewidget.h"
extern vector<vector<SymbolTable>> synbl;
extern vector<vector<RINFL>> rinfl;
extern vector<AINFL> ainfl;

SymbolTableWidget::SymbolTableWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::SymbolTableWidget)
{
    ui->setupUi(this);
}

SymbolTableWidget::~SymbolTableWidget()
{
    delete ui;
}
void SymbolTableWidget::setSyntax(Syntax* syntax){
    this->syntax = syntax;
}
QString typ2QString(int typ){
    QString type;
    switch(typ){
    case 0:  type = "int";break;
    case 1:  type = "float";break;
    case 2:  type = "double";break;
    case 3:  type = "long";break;
    case 4:  type = "short";break;
    case 5:  type = "char";break;
    case 6:  type = "struct";break;
    case -1: type = "void";break;
    }
    return type;
}
QString cat2QString(int cat){
    QString catStr;
    switch(cat){
    case 1: catStr = "function";    break;
    case 2: catStr = "constant";    break;
    case 3: catStr = "type";        break;
    case 4: catStr = "domain";      break;
    case 5: catStr = "variable";    break;
    case 6: catStr = "vn";          break;
    case 7: catStr = "vf";          break;
    default: catStr = "unknown";    break;
    }
    return catStr;
}
void SymbolTableWidget::addItem1(QString name,QString type,QString offset,QString pre_domain,QString cat){
    int n = ui->tableWidget->rowCount();
    ui->tableWidget->setRowCount(n+1);
    QTableWidgetItem *item0 = new QTableWidgetItem(name);
    QTableWidgetItem *item1 = new QTableWidgetItem(type);
    QTableWidgetItem *item2 = new QTableWidgetItem(offset);
    QTableWidgetItem *item3 = new QTableWidgetItem(pre_domain);
    QTableWidgetItem *item4 = new QTableWidgetItem(cat);
    item0->setTextAlignment(Qt::AlignCenter);
    item1->setTextAlignment(Qt::AlignCenter);
    item2->setTextAlignment(Qt::AlignCenter);
    item3->setTextAlignment(Qt::AlignCenter);
    item4->setTextAlignment(Qt::AlignCenter);
    ui->tableWidget->setItem(n,0,item0);
    ui->tableWidget->setItem(n,1,item1);
    ui->tableWidget->setItem(n,2,item2);
    ui->tableWidget->setItem(n,3,item3);
    ui->tableWidget->setItem(n,4,item4);
}
void SymbolTableWidget::addItem2(QString name1,QString offset1,QString size,QString structName){
    int n = ui->tableWidget_2->rowCount();
    ui->tableWidget_2->setRowCount(n+1);
    QTableWidgetItem *item0 = new QTableWidgetItem(name1);
    QTableWidgetItem *item1 = new QTableWidgetItem(offset1);
    QTableWidgetItem *item2 = new QTableWidgetItem(size);
    QTableWidgetItem *item3 = new QTableWidgetItem(structName);
    item0->setTextAlignment(Qt::AlignCenter);
    item1->setTextAlignment(Qt::AlignCenter);
    item2->setTextAlignment(Qt::AlignCenter);
    item3->setTextAlignment(Qt::AlignCenter);
    ui->tableWidget_2->setItem(n,0,item0);
    ui->tableWidget_2->setItem(n,1,item1);
    ui->tableWidget_2->setItem(n,2,item2);
    ui->tableWidget_2->setItem(n,3,item3);
}
void SymbolTableWidget::addItem3(QString name2,QString type2,QString len,QString low,QString up,QString offset2){
    int n = ui->tableWidget_3->rowCount();
    ui->tableWidget_3->setRowCount(n+1);
    QTableWidgetItem *item0 = new QTableWidgetItem(name2);
    QTableWidgetItem *item1 = new QTableWidgetItem(type2);
    QTableWidgetItem *item2 = new QTableWidgetItem(len);
    QTableWidgetItem *item3 = new QTableWidgetItem(low);
    QTableWidgetItem *item4 = new QTableWidgetItem(up);
    QTableWidgetItem *item5 = new QTableWidgetItem(offset2);
    item0->setTextAlignment(Qt::AlignCenter);
    item1->setTextAlignment(Qt::AlignCenter);
    item2->setTextAlignment(Qt::AlignCenter);
    item3->setTextAlignment(Qt::AlignCenter);
    item4->setTextAlignment(Qt::AlignCenter);
    item5->setTextAlignment(Qt::AlignCenter);
    ui->tableWidget_3->setItem(n,0,item0);
    ui->tableWidget_3->setItem(n,1,item1);
    ui->tableWidget_3->setItem(n,2,item2);
    ui->tableWidget_3->setItem(n,3,item3);
    ui->tableWidget_3->setItem(n,4,item4);
    ui->tableWidget_3->setItem(n,5,item5);
}
void SymbolTableWidget::showTable(){
    // 1. tablewidget
    QString name,type,offset,pre_domain,cat;
    for(int i = 0;i<synbl.size();i++){
        for(int j = 0;j<synbl[i].size();j++){
            name = "";type = ""; offset = ""; pre_domain = ""; cat = "";
            if(j==0){
                name = "scope";
                type = QString::number(i);
                if(i == 0){
                    offset = "Global Scope";
                }else{
                    offset = QString::fromStdString(synbl[i][0].domainName);
                }
            }else{
                name = QString::fromStdString(synbl[i][j].name);
                type = typ2QString(synbl[i][j].typ);
                offset = QString::number(synbl[i][j].offset);
                pre_domain = QString::number(synbl[i][j].prelev);
                cat = cat2QString(synbl[i][j].cat);
            }

            this->addItem1(name,type,offset,pre_domain,cat);
        }
    }
    // 2. tablewidget_2
    QString name1,offset1,size,structName;

    for(int i = 0;i<rinfl.size();i++){
        name1 = "";offset1 = "",size = "";structName = "";
        // 类型定义
        offset1 = QString::number(rinfl[i][0].offset);
        size = QString::number(rinfl[i][0].size);
        structName = QString::fromStdString(rinfl[i][0].structName);
        this->addItem2(name1,offset1,size,structName);
        // 类型定义的域内变量
        vector<Domain>member = rinfl[i][0].memberName;
        for(int k = 0;k<member.size();k++){
            name1 = "";offset1 = "",size = "";structName = "";
            name1 = QString::fromStdString(member[k].id);
            offset1 = QString::number(member[k].offset);
            size = typ2QString(member[k].typ);
            this->addItem2(name1,offset1,size,structName);
        }
        // 具体的类型变量
        for(int j = 1;j<rinfl[i].size();j++){
            name1 = "";offset1 = "",size = "";structName = "";
            name1 = QString::fromStdString(rinfl[i][j].name);
            offset1 = QString::number(rinfl[i][j].offset);
            size = QString::number(rinfl[i][j].size);
            structName = QString::fromStdString(rinfl[i][j].structName);
            this->addItem2(name1,offset1,size,structName);
            // 输出每一个变量的域内变量
            vector<Domain>member = rinfl[i][j].memberName;
            for(int k = 0;k<member.size();k++){
                name1 = "";offset1 = "",size = "";structName = "";
                name1 = QString::fromStdString(member[k].id);
                offset1 = QString::number(member[k].offset);
                size = typ2QString(member[k].typ);
                this->addItem2(name1,offset1,size,structName);
            }
        }
    }
    // 3. tablewidget_3
    QString name2,type2,len,low,up,size2,offset2;
    for(int i = 0;i<ainfl.size();i++){
        name2 = QString::fromStdString(ainfl[i].name);
        type2 = typ2QString(ainfl[i].typ);
        len = QString::number(ainfl[i].len);
        low = QString::number(ainfl[i].low);
        up = QString::number(ainfl[i].up);
        offset2 = QString::number(ainfl[i].offset);
        this->addItem3(name2,type2,len,low,up,offset2);
    }
}
